package com.unbiz.common.lang;

import java.io.IOException;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;

public class Yield {

	/**
	 * A take on yield return.
	 * 
	 * <pre>
	 * public static &lt;S, T&gt; Iterable&lt;T&gt; map(final Iterable&lt;S&gt; list, final Function1&lt;S, T&gt; mapping) {
	 * 	for (S element : list)
	 * 		yield(mapping.apply(element));
	 * }
	 * </pre>
	 * 
	 * or:
	 * 
	 * <pre>
	 * public Iterator&lt;Integer&gt; genFib() {
	 * 	long a = 0;
	 * 	long b = 0;
	 * 	while (b &gt;= 0) {
	 * 		yield(a);
	 * 		long c = a + b;
	 * 		a = b;
	 * 		b = c;
	 * 	}
	 * }
	 * </pre>
	 */
	public static <T> void yield(final T value) {
		return; // yup, that's about all we need
	}
	
	public static class Generator<T> implements java.util.Iterator<T>, java.lang.Iterable<T>, java.io.Closeable{
		private LinkedBlockingQueue<T> queue;
		private int $state;
		Consumer<Generator<T>> consumer;
		public  Generator(){
			queue = new LinkedBlockingQueue<T>(1);
		}
		
		public Generator(Consumer<Generator<T>> consumer){
			this.consumer = consumer;
		}
		
		public void yield(final T value) {
			try {
				queue.put(value);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return ; // yup, that's about all we need
		}

		@Override
		public void close() throws IOException {
			// TODO Auto-generated method stub
			$state = 4;
			queue.clear();
		}

		@Override
		public Iterator<T> iterator() {
			// TODO Auto-generated method stub
			if (($state == 0))
            {
               $state = 1;
               return this;
            }
			else{
				return new Generator<T>();
			}
		}

		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public T next() {
			// TODO Auto-generated method stub
			consumer.accept(this);
			return null;
		}

		
	}
}
